﻿using System;
using System.Device.Location;

namespace INdTFramework.Maps
{
    /// <summary>
    /// Specialized class on getting the current geographical position.
    /// </summary>
    public class Geolocation
    {
        private GeoCoordinateWatcher watcher;

        /// <summary>
        /// Status of the current geographical position.
        /// </summary>
        public GeoPositionStatus Status { get; set; }

        /// <summary>
        /// Error message for unavailable status.
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// Geographic coordinate.
        /// </summary>
        public double Latitude { get; private set; }

        /// <summary>
        /// Geographic coordinate.
        /// </summary>
        public double Longitude { get; private set; }

        /// <summary>
        /// Indicates if initialization of the geographical position watcher finished or not.
        /// </summary>
        public bool IsFinished { get; private set; }

        /// <summary>
        /// Constructor method.
        /// </summary>
        public Geolocation() 
        {
            watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            watcher.MovementThreshold = 20;

            watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(StatusChanged);
            watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(PositionChanged);

            watcher.Start();        
        }

        private void StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case GeoPositionStatus.Initializing:
                    IsFinished = false;
                    break;
                case GeoPositionStatus.Disabled:
                    Message = "The location service is disabled or is not supported.";
                    IsFinished = true;
                    break;
                case GeoPositionStatus.NoData:
                    Message = "Unavailable location data.";
                    IsFinished = true;
                    break;
                case GeoPositionStatus.Ready:
                    IsFinished = true;
                    break;
            }

            Status = e.Status;
        }


        private void PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Latitude = e.Position.Location.Latitude;
            Longitude = e.Position.Location.Longitude;
        }


        /// <summary>
        /// Converts a coordinate to radians degrees.
        /// </summary>
        /// <param name="coordinate">Coordinate value to be converted.</param>
        /// <param name="geographicCoordinate">Definition of the coordinate to be converted. Can be 'latitude' or 'longitude'.</param>
        /// <returns></returns>
        public string ConvertDegrees(double coordinate, string geographicCoordinate)
        {
            char vPont;
 
            if (geographicCoordinate == "latitude")
            {
                vPont = coordinate < 0 ? 'S' : 'N';
            }else {
                vPont = coordinate < 0 ? 'W' : 'E';
            }

           int sec = (int)Math.Round(coordinate * 3600);
           int deg = sec / 3600;
           sec = Math.Abs(sec % 3600);
           int min = sec / 60;
           sec %= 60;

            if(deg < 0){
                deg = 0 - deg; 
            }

           string value = deg + "°" + min + "'" + sec + '"' + vPont;

           return value;
       }
    }
}
